package lei;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import jdk.jfr.DataAmount;
import lombok.Data;

import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * @className: Main2
 * @author: xl
 * @date: 2025/7/19 20:24
 * @Version: 1.0
 * @description: 常用的接口式函数
 *
 *
 * Supplier<T>：无参数，返回结果（T get()）
 * Consumer<T>：接收参数，无返回（void accept(T t)）
 * Function<T,R>：接收参数，返回结果（R apply(T t)）
 * Predicate<T>：接收参数，返回布尔值（boolean test(T t)）
 * Runnable：无参数，无返回（void run()）
 */

public class Main2 {
    public static void main(String[] args) {

        /**
         * 自定义的函数式接口
         * Greeting03
         * 作用：接受一个参数并打印
         * 抽象方法：void sayHello(String name)
         */
        //方式一：使用匿名内部类的方式 实现
        new Greeting03() {
            @Override
            public void sayHello(String name) {
                System.out.println("Hello, " + name + "!");
            }
        }.sayHello("John");


        //方式二：使用Lambda表达式实现
        Greeting03 greeting = name -> System.out.println("Hello, " + name + "!");
        greeting.sayHello("Alice");

        //方式三：使用Lambda表达式实现  一般不这样子写
        ((Greeting03) name -> System.out.println("Hello, " + name + "!")).sayHello("Bob");


        /**
         * Supplier<T>：无参数，返回结果（T get()）
         */

        System.out.println(new Supplier<String>() {
            @Override
            public String get() {
                return "Hello World!";
            }
        }.get());

        Supplier number = () -> {
            Random random = new Random();
            return random.nextInt(100);
        };

        System.out.println(number.get());

        System.out.println(((Supplier) () -> {
            return "Hello World!";
        }).get());


        /**
         * Consumer<T>：接收参数，无返回（void accept(T t)）
         * 作用：接受一个参数并执行操作
         * 抽象方法：void accept(T t)
         * 参数：T t
         */
        new Consumer<String>() {
            @Override
            public void accept(String name) {
                System.out.println("Hello, " + name + "!");
            }
        }.accept("John");


        /**
         * Function<T,R>：接收参数，返回结果 （R apply(T t)）
         * 作用：接受一个参数并返回结果
         * 抽象方法：R apply(T t)
         * 参数：T t
         */
        System.out.println(new Function<String, String>() {
            @Override
            public String apply(String name) {
                return "Hello, " + name + "!";
            }
        }.apply("John"));


        /**
         * Predicate<T>：接收参数，返回布尔值（boolean test(T t)）
         * 作用：接受一个参数并返回布尔值
         * 抽象方法：boolean test(T t)
         * 参数：T t
         */
        System.out.println(new Predicate<String>() {
            @Override
            public boolean test(String name) {
                return name.length() > 5;
            }
        }.test("John"));


        /**
         * Runnable：无参数，无返回（void run()）
         * 作用：无参数，无返回，执行操作
         * 抽象方法：void run()
         * 参数：无
         */
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello World!");
            }
        }).start();


        // 创建一个字符串列表
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Eve");

        // 1. 按字符串长度排序 - 匿名内部类方式
        Collections.sort(names, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                return Integer.compare(s1.length(), s2.length());
            }
        });
        System.out.println("按长度排序: " + names);

        // 2. 按字符串长度排序 - Lambda表达式方式
        List<String> names2 = Arrays.asList("Alice", "Bob", "Charlie", "David", "Eve");
        Collections.sort(names2, (s1, s2) -> Integer.compare(s1.length(), s2.length()));
        System.out.println("Lambda按长度排序: " + names2);

        // 3. 按字符串长度排序 - 使用 Comparator.comparing 方法
        List<String> names3 = Arrays.asList("Alice", "Bob", "Charlie", "David", "Eve");
        Collections.sort(names3, Comparator.comparing(String::length));
        System.out.println("使用方法引用按长度排序: " + names3);

        // 4. 逆序排序
        List<String> names4 = Arrays.asList("Alice", "Bob", "Charlie", "David", "Eve");
        Collections.sort(names4, Comparator.comparing(String::length).reversed());
        System.out.println("按长度逆序排序: " + names4);

        // 5. 多重排序：先按长度，再按字母顺序
        List<String> names5 = Arrays.asList("Alice", "Bob", "Charlie", "David", "Eve", "Ann");
        Collections.sort(names5, Comparator.comparing(String::length).thenComparing(Comparator.naturalOrder()));
        System.out.println("多重排序: " + names5);

        // 6. 自定义对象排序示例
        List<Person> people = Arrays.asList(
                new Person("Alice", 30),
                new Person("Bob", 25),
                new Person("Bob", 23),
                new Person("Charlie", 35),
                new Person("Alice", 12)
        );

        // 按年龄排序
        people.sort(Comparator.comparing(Person::getAge));
        System.out.println("按年龄排序: " + people);

        // 按姓名排序
        people.sort(Comparator.comparing(Person::getName));
        System.out.println("按姓名排序: " + people);

        //先按姓名排序，再按年龄排序
        people.sort(Comparator.comparing(Person::getName).thenComparing(Person::getAge));
        System.out.println("先按姓名排序，再按年龄排序: " + people);

        Collections.sort(people, Comparator.comparing(Person::getName).thenComparing(Person::getAge));

        List<Person> sortedPeople = people.stream().sorted(Comparator.comparing(Person::getName).thenComparing(Person::getAge)).collect(Collectors.toList());
        System.out.println("Collections.sort: " + sortedPeople);


        MyZoo myZoo = new MyZoo();
        myZoo.setName("myZoo");
        myZoo.setAge(10);
        myZoo.setColor("red");
        myZoo.setAddressList(Arrays.asList(
                new Address("3", "Street 1", "City 1", "three"),
                new Address("1", "Street 2", "City 1", "one"),
                new Address("1", "Street 3", "City 3", "two")
        ));


        // 将 myZoo 对象转换为 JSON 字符串
        String jsonString = JSON.toJSONString(myZoo);
        System.out.println("序列化为JSON: " + jsonString);

        // 在 Main2.java 的 main 方法中添加以下代码
        /**
         *
         myZoo.getAddressList().stream()
            获取 myZoo 对象中的 addressList 列表
            使用 stream() 方法将其转换为流，以便进行函数式操作
         sorted(Comparator.comparing(Address::getId).thenComparing(Address::getStreet))
            对流中的 Address 对象进行排序
            首先使用 Comparator.comparing(Address::getId) 按 id 字段排序
            然后使用 thenComparing(Address::getStreet) 在 id 相同的情况下按 street 字段排序
            这是一个复合排序条件
         collect(Collectors.collectingAndThen(...))
            使用 collect 方法收集流中的元素
            Collectors.collectingAndThen 允许我们在收集后执行额外的操作
         Collectors.toList()
            将排序后的流收集为一个 List<Address> 列表
         list -> { ... }（Function）
            这是一个函数式接口，接收收集到的列表作为参数
            在这个函数中创建一个新的 MyZoo 对象并设置属性：
                newZoo.setName(myZoo.getName()) - 复制原始名称
                newZoo.setAge(myZoo.getAge()) - 复制原始年龄
                newZoo.setColor(myZoo.getColor()) - 复制原始颜色
                newZoo.setAddressList(list) - 设置排序后的地址列表
            最后返回新创建的 MyZoo 对象
         */
        MyZoo sortedMyZoo = myZoo.getAddressList().stream()
                .sorted(Comparator.comparing(Address::getId).thenComparing(Address::getStreet))
                .collect(Collectors.collectingAndThen(
                        Collectors.toList(),
                        list -> {
                            MyZoo newZoo = new MyZoo();
                            newZoo.setName(myZoo.getName());
                            newZoo.setAge(myZoo.getAge());
                            newZoo.setColor(myZoo.getColor());
                            newZoo.setAddressList(list);
                            return newZoo;
                        }
                ));

        System.out.println("排序后的 MyZoo: " + JSON.toJSONString(sortedMyZoo));


        // 直接修改原对象的 addressList
        myZoo.setAddressList(
                myZoo.getAddressList().stream()
                        .sorted(Comparator.comparing(Address::getId).thenComparing(Address::getStreet))
                        .collect(Collectors.toList())
        );

        System.out.println("排序后的 MyZoo: " + JSON.toJSONString(myZoo));


    }
}

@FunctionalInterface
interface Greeting03 {

    void sayHello(String name);
}

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}


@Data
class MyZoo extends Zoo {
    private List<Address> addressList;

    public MyZoo() {
        super();
    }

    public MyZoo(String name, int age, String color, List<Address> addressList) {
        super(name, age, color);
        this.addressList = addressList;
    }


}

@Data
class Zoo {
    private String name;
    private int age;
    private String color;

    public Zoo() {

    }

    public Zoo(String name, int age, String color) {
        this.name = name;
        this.age = age;
        this.color = color;
    }


}

@Data
class Address {
    private String id;

    private String street;
    private String city;
    private String country;

    // 添加构造函数
    public Address() {
    }

    public Address(String id, String street, String city, String country) {
        this.id = id;
        this.street = street;
        this.city = city;
        this.country = country;
    }


}



